<?php
namespace App\Http\Model;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use App\Http\Constant;
use App\Http\Model\RbacRole;
use Illuminate\Support\Facades\DB;

class RbacNode extends Model{
	protected $table = 'rbac_node';
	protected $primaryKey = 'id';

	public function createNode(Request $request){
		$exist_nodes = $this->where('node_name', '=', $request->input('name'))
			->where('node_path', '=', $request->input('path'))
			->get()
			->toArray();
		if(0 != count($exist_nodes)){
			throw new \Exception('Rbac node [name='.$request->input('name').' and path='.$request->input('path').'] exists.', Constant::EC_RBAC_NODE_EXISTS);
		}else{
			if($request->input('pid') != 0){
				$parent_node = DB::table($this->table)->where('id', '=', $request->input('pid'))->get()->toArray();
				$parent_node = json_decode(json_encode($parent_node), true);
			}else{
				$parent_node = [1];
			}
			if(0 == count($parent_node)){
				throw new \Exception('Parent rbac node [id='.$request->input('pid').'] not exists.', Constant::EC_RBAC_NODE_EXISTS);
			}else{
				$this->pid = $request->input('pid');
				$this->node_name = $request->input('name');
				$this->node_path = $request->input('path');
				$this->type = $request->input('type');
				$this->save();
				return $this->id;
			}
		}
	}

	public function editNode(Request $request){
		$exist_nodes = $this->where('node_name', '=', $request->input('name'))
			->where('node_path', '=', $request->input('path'))
			->where('id', '<>', $request->input('id'))
			->get()
			->toArray();
		if(0 != count($exist_nodes)){
			throw new \Exception('Rbac node [name='.$request->input('name').' and path='.$request->input('path').'] exists.', Constant::EC_RBAC_NODE_EXISTS);
		}else{
			if($request->input('pid') != 0){
				$parent_node = DB::table($this->table)->where('id', '=', $request->input('pid'))->get()->toArray();
				$parent_node = json_decode(json_encode($parent_node), true);
			}else{
				$parent_node = [1];
			}
			if(0 == count($parent_node)){
				throw new \Exception('Parent rbac node [id='.$request->input('pid').'] not exists.', Constant::EC_RBAC_NODE_EXISTS);
			}else{
				$this->pid = $request->input('pid');
				$this->node_name = $request->input('name');
				$this->node_path = $request->input('path');
				$this->type = $request->input('type');
				$update_data = [
					'pid' => $request->input('pid'),
					'node_name' => $request->input('name'),
					'node_path' => $request->input('path'),
					'type' => $request->input('type'),
				];
				return $this->where('id', '=', $request->input('id'))->update($update_data) !== false;
			}
		}
	}

	public function deleteNode(Request $request){
		$node_id = $request->input('id');
		$children = $this->where('pid', '=', $node_id)
			->whereIn('status', [
				Constant::TFEX_RBAC_NODE_STATUS_OPEN
			])->get()->toArray();
		if(0 != count($children)){
			throw new \Exception('Rbac node [id='.$node_id.'] has children and can not be deleted.', Constant::EC_RBAC_NODE_CAN_NOT_CLOSED);
		}else{
			$update_data = [
				'status' => Constant::TFEX_RBAC_NODE_STATUS_DELETE,
			];
			return $this->where('id', '=', $node_id)->update($update_data) !== false;
		}
	}

	public function listNodes($as_navigation=false, $be_tree=true){
		$node_status = [Constant::TFEX_RBAC_NODE_STATUS_OPEN, Constant::TFEX_RBAC_NODE_STATUS_CLOSE];
		if($as_navigation){
			$node_type = [Constant::TFEX_RBAC_NODE_TYPE_SHOW, Constant::TFEX_RBAC_NODE_TYPE_PACKAGE];
		}else{
			$node_type = [Constant::TFEX_RBAC_NODE_TYPE_SHOW, Constant::TFEX_RBAC_NODE_TYPE_PACKAGE, Constant::TFEX_RBAC_NODE_TYPE_HIDE];
		}
		$access_nodes = DB::table($this->table)->whereIn('status', $node_status)->whereIn('type', $node_type)->get()->toArray();
		$access_nodes = json_decode(json_encode($access_nodes), true);
		if($be_tree){
			$access_nodes = $this->_getTree($access_nodes, 0);
		}
		return $access_nodes;
	}
        
        //根据方法名称获取状态
        public function getNodeListByNodePath($path){
            $node_status = [Constant::TFEX_RBAC_NODE_STATUS_OPEN, Constant::TFEX_RBAC_NODE_STATUS_CLOSE];
            $node_type   = [Constant::TFEX_RBAC_NODE_TYPE_SHOW, Constant::TFEX_RBAC_NODE_TYPE_PACKAGE, Constant::TFEX_RBAC_NODE_TYPE_HIDE];
            
            //根据路径名称和状态,类型获取是否存在此信息
            $access_info = DB::table($this->table)->whereIn('node_path', $path)->whereIn('status', $node_status)->whereIn('type', $node_type)->get()->toArray();
            if(0 !== count($access_info)){
                return array_column(json_decode(json_encode($access_info), true),'node_path');
            } else {
                return '';
            }
        }

	public function listRoleNodes($role_id){
        $role = DB::table('rbac_role')->where('id', '=', $role_id)->get()->toArray();
        $role = json_decode(json_encode($role), true);
        if(0 == count($role)){
            $access_data = [];
        }else{
            $role_nodes_id = $role[0]['role_nodes'];
            $access_data = DB::table('rbac_node')->whereIn('id', explode(',', $role_nodes_id))->get()->toArray();
        	$access_data = json_decode(json_encode($access_data), true);
            $access_data = $this->_getTree($access_data, 0);
        }
        return $access_data;
	}

	private function _getTree($nodes, $pid=0){
		$sub_nodes = array();
		foreach ($nodes as $value) {
			if($value['pid'] == $pid){
				$sub_nodes_data = $this->_getTree($nodes, $value['id']);
				if(0 != count($sub_nodes_data)){
					$value['_sub'] = $sub_nodes_data;
				}
				array_push($sub_nodes, $value);
			}else{
				continue;
			}
		}
		return $sub_nodes;
	}
}